﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Microsoft.VisualBasic;

namespace 测试
{
    public partial class Form1 : Form
    {
        static bool curColor = false;
        static KeyValuePair<int, int> NextChessLocation;
        static List<KeyValuePair<int, int>>[,] arrayLists = new List<KeyValuePair<int, int>>[19, 19];
        static List<KeyValuePair<int, int>> path = new List<KeyValuePair<int, int>>();

        static int[,] vs = new int[19, 19];
        static int ct = 0;
        public Form1()
        {
            InitializeComponent();
            init();
        }

        static void init()
        {
            
            //初始化二位数组
            for (int i = 0; i < 19; i++)
            {
                for (int j = 0; j < 19; j++)
                {
                    arrayLists[i, j] = new List<KeyValuePair<int, int>>();
                    vs[i, j] = 0;
                }
            }

            //读入字符串
            string s = ReadStringFromFile(@".\first.sgf");

            //解析字符串
            bool isFirstChess = true;
            
            for (int i = 10; i < s.Length; i++)
            {
                string str = s.Substring(i - 10, 11);
                if (str[1] == str[7] && str[1] == '[' && str[4] == str[10] && str[4] == ']' && str[5] == ';')
                {
                    AddToTree(arrayLists, str[2] - 'a', str[3] - 'a', str[8] - 'a', str[9] - 'a');
                    if (isFirstChess)
                    {
                        isFirstChess = false;
                        NextChessLocation = new KeyValuePair<int, int>(str[2] - 'a', str[3] - 'a');
                        path.Add(NextChessLocation);
                    }
                }
            }
            for (int i = 5; i < s.Length; i++)
            {
                string str = s.Substring(i - 5, 6);
                if (str[1] == '[' && str[4] == ']' && str[5] == '(')
                {
                    str = str.Substring(0, str.Length - 1);
                    int count = 0;
                    for (int j = i; j < s.Length; j++)
                    {
                        if (s[j] == '(')
                        {
                            count++;
                            if (count == 1)
                            {
                                string tile = s.Substring(j + 1, 6);
                                str += tile;
                                AddToTree(arrayLists, str[2] - 'a', str[3] - 'a', str[8] - 'a', str[9] - 'a');
                                str = str.Substring(0, 5);
                            }
                        }
                        else if (s[j] == ')')
                        {
                            count--;
                        }
                    }
                }
            }
            for (int i = 0; i < s.Length; i++)
            {
                if (s[i] == 'P' && s[i + 1] == 'L')
                {
                    if (s[i + 3] == 'W')
                    {
                        curColor = true;
                    }
                }
            }
        }

        /// <summary>
        /// 从文件中读取字符串
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        static string ReadStringFromFile(string str)
        {
            FileStream fileStream = new FileStream(str, FileMode.Open, FileAccess.Read);
            byte[] buffer = new byte[1024 * 1024];
            int r = fileStream.Read(buffer, 0, buffer.Length);
            string s = Encoding.Default.GetString(buffer, 0, r);
            fileStream.Close();
            fileStream.Dispose();
            return s;
        }
        /// <summary>
        /// 根据树中边的信息，向邻接表中添加
        /// </summary>
        /// <param name="arrayLists"></param>
        /// <param name="i"></param>
        /// <param name="j"></param>
        /// <param name="k"></param>
        /// <param name="p"></param>
        static void AddToTree(List<KeyValuePair<int, int>>[,] arrayLists, int i, int j, int k, int p)
        {
            arrayLists[i, j].Add(new KeyValuePair<int, int>(k, p));
        }
        /// <summary>
        /// 绘制棋盘
        /// </summary>
        /// <param name="e"></param>
        protected override void OnPaint(PaintEventArgs e)
        {
            Pen pen = new Pen(Color.Black, 1);
            for(int i = 10; i <= 550; i += 30)
            {
                PrintALine(i, 10, i, 550, pen, e);
            }
            for (int i = 10; i <= 550; i += 30)
            {
                PrintALine(10, i, 550, i, pen, e);
            }
            DrawSmallCricle(30 * 3 + 7, 30 * 3 + 7, Color.Black);
            DrawSmallCricle(30 * 9 + 7, 30 * 9 + 7, Color.Black);
            DrawSmallCricle(30 * 3 + 7, 30 * 9 + 7, Color.Black);
            DrawSmallCricle(30 * 3 + 7, 30 * 15 + 7, Color.Black);
            DrawSmallCricle(30 * 15 + 7, 30 * 3 + 7, Color.Black);
            DrawSmallCricle(30 * 15 + 7, 30 * 15 + 7, Color.Black);
            DrawSmallCricle(30 * 9 + 7, 30 * 3 + 7, Color.Black);
            DrawSmallCricle(30 * 15 + 7, 30 * 9 + 7, Color.Black);
            DrawSmallCricle(30 * 9 + 7, 30 * 15 + 7, Color.Black);
            for (int i = 0; i < 19; i++)
            {
                for(int j = 0; j < 19; j ++)
                {
                    if(vs[i,j] !=0)
                        DrawCricle(30 * i, 30 * j, vs[i, j] == -1 ? Color.White : Color.Black);
                }
            }
            pen.Dispose();
        }
        /// <summary>
        /// 画直线
        /// </summary>
        /// <param name="x">直线起点坐标x</param>
        /// <param name="y">直线起点坐标y</param>
        /// <param name="xx">直线终点坐标x</param>
        /// <param name="yy">直线终点坐标y</param>
        /// <param name="pen"></param>
        /// <param name="e"></param>
        private void PrintALine(int x, int y, int xx, int yy, Pen pen, PaintEventArgs e)
        {
            e.Graphics.DrawLine(pen, x, y, xx, yy);
        }
        
        /// <summary>
        /// 画棋子
        /// </summary>
        /// <param name="x">棋子外切矩形的左上点坐标x</param>
        /// <param name="y">棋子外切矩形的左上点坐标y</param>
        /// <param name="xx">棋子外切矩形长</param>
        /// <param name="yy">棋子外切矩形宽</param>
        /// <param name="color">棋子颜色</param>
        private void DrawCricle(int x, int y, Color color)
        {
            Graphics g = this.CreateGraphics();
            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
            g.FillEllipse(new SolidBrush(color), x, y, 20, 20);
        }
        private void DrawSmallCricle(int x, int y, Color color)
        {
            Graphics g = this.CreateGraphics();
            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
            g.FillEllipse(new SolidBrush(color), x, y, 6, 6);
        }
        private void btnNext_Click(object sender, EventArgs e)
        {       
            int x = NextChessLocation.Key;
            int y = NextChessLocation.Value;
            if (ct == 0)
            {
                DrawCricle(30 * x, 30 * y, Color.White);
                vs[x, y] = -1;
            }
            string temp = "下一步可选位置:";

            if(ct >= path.Count)
            {
                MessageBox.Show("请输入下一步棋子位置！！");
                ct--;
                return;
            }
            
            foreach (var el in arrayLists[path[ct].Key, path[ct].Value])
            {
                temp += string.Format(" [{0},{1}]", el.Key, el.Value);
            }
            if(arrayLists[path[ct].Key, path[ct].Value].Count == 0)
            {
                temp = "棋谱已结束";
            }
            this.lable.Text = temp;
            ct ++;
        }

        private void btnZou_Click(object sender, EventArgs e)
        {
            if (this.XTextBox1.Text != "" && this.XTextBox1.Text != "")
            {
                int x = Convert.ToInt32(this.XTextBox1.Text);
                int y = Convert.ToInt32(this.YTextBox.Text);
                curColor = !curColor;
                DrawCricle(30 * x, 30 * y, curColor ? Color.White : Color.Black);
                vs[x, y] = curColor ? -1 : 1;
                this.XTextBox1.Text = "";
                this.YTextBox.Text = "";
                path.Add(new KeyValuePair<int, int>(x, y));
            }
            else
            {
                MessageBox.Show("不能为空");
            }
        }
    }
}
